﻿using System;
using System.Data.Linq;
using System.Linq;

namespace Storage.EntityModels
{
    #region Public enums: Gender, Smoker
    
    #pragma warning disable 1591
    
    /// <summary>
    /// Defines the sex of a person.
    /// </summary>
    public enum Gender
    {
        Unknown,
        Female,
        Male
    } 

    /// <summary>
    /// Defines if a person is a smoker or not.
    /// </summary>
    public enum Smoker
    {
        Unknown,
        NotSmoker,
        Smoker
    }

    #pragma warning restore 1591

    #endregion

    #region User

    /// <summary>
    /// This class represents the Users table into entities model; 
    /// </summary>
    public partial class User : IPersistable
    { 
        #region Public properties: Gender, Smoker, Email

        /// <summary>
        /// Gets or sets the Gender of the user.
        /// </summary>
        [DBField("GenderAsByte")]
        public Gender Gender
        {
            get
            {
                if (GenderAsByte == 0)
                    return EntityModels.Gender.Unknown;

                if (GenderAsByte == 1)
                    return EntityModels.Gender.Female;

                if (GenderAsByte == 2)
                    return EntityModels.Gender.Male;

                throw new ArgumentException("Ma che Gender mi passi?");
            }
            set
            {
                GenderAsByte = (byte)value;
            }
        }

        /// <summary>
        /// Gets or sets the Smoker info for the user.
        /// </summary>
        [DBField("SmokerAsByte")]
        public Smoker Smoker
        {
            get
            {
                switch (SmokerAsByte)
                {
                    case 0:
                        return EntityModels.Smoker.Unknown;

                    case 1:
                        return EntityModels.Smoker.NotSmoker;

                    case 2:
                        return EntityModels.Smoker.Smoker;

                    default:
                        throw new ArgumentException("Smoker enum in input not valid.");
                }
            }
            set
            {
                SmokerAsByte = (byte)value;
            }
        }

        /// <summary>
        /// Gets or sets the Email for the user.
        /// </summary>
        public string Email 
        {
            get
            {
                return StorageManager.Instance.Entities.User_selectAspEmail(Username).First().Email;
            }
            set
            {
                StorageManager.Instance.Entities.User_updateAspEmail(Username, value);
            }
        }

        /// <summary>
        /// Gets the Age.
        /// </summary>
        /// <remarks>
        /// The set method is empty. So it doesn't anything.
        /// </remarks>
        public int? Age
        {
            get
            {
                return StorageManager.Instance.Entities.GetAge(Birthday);
            }
            set
            { 
            }
        }


        #endregion

        #region Partial methods: OnValidate, OnCreated

        partial void OnValidate(ChangeAction action)
        {
#if DEBUG
            if (BookedIn)
            {
                // TODO: add IsBookedIn validation logic.
            }
#endif
        }

        partial void OnCreated()
        {
            // Sets default values for stats fields.
            CarCo2Emissions = 135;
            CarFuelConsumption = 18;
            BookedIn = true;
            GenderAsByte = 0;
        }

        #endregion

        #region IPersistable Members
        
        /// <summary>
        /// This function inserts a User entity into Users table.
        /// </summary>
        /// <param name="db">The BaseTripLoaDataContext.</param>
        public void OnInsert(BaseTripLoaDataContext db)
        {
            int? userId = 0;

            db.User_insert(ref userId, Username, Name, Surname, GenderAsByte, Birthday, 
                City, Address, PhoneNumber, SmokerAsByte, DrivingLicence, BookedIn, Language);

            Id = userId.Value;
        }

        /// <summary>
        /// This function updates a User into Users table.
        /// </summary>
        /// <param name="db">The BaseTripLoaDataContext.</param>
        public void OnUpdate(BaseTripLoaDataContext db)
        {
            // Not yet needed.
        }

        #endregion
    }

    #endregion
}